package com.newflypig.jblog.service.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.newflypig.jblog.dao.IBaseDAO;
import com.newflypig.jblog.model.Pager;
import com.newflypig.jblog.service.IBaseService;

/**
 *  公用服务类，实现大多数常用操作
 *	@author newflypig
 *	time：2015年11月23日
 *
 */
public abstract class BaseServiceImpl<T extends Serializable> implements IBaseService<T> {

	protected abstract IBaseDAO<T> getDao();
	
	protected Class<T> entityClazz;
	 
    public BaseServiceImpl() {        
        resovleClazzInfo();
    }
     
	@SuppressWarnings("unchecked")
	private void resovleClazzInfo() {
        Type genType = getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        entityClazz = (Class<T>) params[0];
    }
	
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public Serializable save(T entity){
		return this.getDao().save(entity);
	}
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void delete(T entity) {
		this.getDao().delete(entity);
	}
	
	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
	public T findById(Integer id) {
		return this.getDao().findById(id);
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void update(T entity){
		this.getDao().update(entity);
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public void deleteById(Integer id) {
		this.getDao().deleteById(id);
	}
	
	@Override
	@Transactional(propagation=Propagation.NOT_SUPPORTED, readOnly = true)
	public List<T> findAll() {
		return this.getDao().findAll();
	}
	
	/**
	 * 指定分页容量的分页函数
	 * @param dc
	 * @param dc2
	 * @param page
	 * @return
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED, readOnly = true)
	protected Pager<T> generatePage(DetachedCriteria dc, DetachedCriteria dc2, Integer page, Integer numPerPage, Integer showPage) {
		Pager<T> pagerT=new Pager<T>();
		
		//向上取整得到总页数
		int totalPages = (int) Math.ceil( (double) this.getDao().getCount(dc2) / numPerPage );
		pagerT.setTotalSize( totalPages );
		//设置当前页
		pagerT.setCurrentPage( page );
		
		//根据dc，查询数据库，给出数据
		pagerT.setData( this.getDao().findPager(dc, page, numPerPage) );
		if(pagerT.getData().size() == 0)
			return pagerT;
		
		//分页逻辑
		List<String[]> urls=new ArrayList<String[]>();
		if(page == 1 && totalPages > 1){
			urls.add(new String[]{"下一页","2"});
			int i = 0;
			for(i = 3; i < showPage; i++){
				if(i < totalPages)
					urls.add(new String[]{String.valueOf(i),String.valueOf(i)});
				else if(i == totalPages)
					urls.add(new String[]{"尾页",String.valueOf(i)});
				else
					break;
			}
			if(i-1 != totalPages)
				urls.add(new String[]{"尾页",String.valueOf(totalPages)});
		}
		else if(page==1){}
		else{
			urls.add(new String[]{"首页",String.valueOf(1)});
			urls.add(new String[]{"上一页",String.valueOf(page-1)});
			int eage = showPage / 2;
			int min=1;int max=totalPages;
			min=Math.max(min, page-eage);
			if(page+eage>totalPages && min-(page+eage-totalPages)>0)
				min=min-(page+eage-totalPages);
			max=Math.min(max, page+eage);
			if(page-eage<1 && max+((eage+1)-page)<=totalPages)
				max=max+eage+1-page;
			for(int i=min;i<=max;i++)
				urls.add(new String[]{String.valueOf(i),String.valueOf(i)});			
			if(page!=totalPages){
				urls.add(new String[]{"下一页",String.valueOf(page+1)});
				urls.add(new String[]{"尾页",String.valueOf(totalPages)});
			}
		}
		pagerT.setUrls(urls);
		return pagerT;
	}
}
